package com.meta.nd.filter.utils;

import com.meta.common.ConstDef;
import com.meta.nd.filter.bo.FilterParamDef;
import com.meta.nd.filter.vo.FilterFd;
import com.meta.nd.filter.vo.ResultFd;
import com.meta.nd.vo.Fd;
import com.meta.nd.vo.Nd;

import java.util.List;

public class FilterDefBuilder {

    private Nd nd;
    FilterParamDef filterParamDef = new FilterParamDef();

    public static FilterDefBuilder createBuilder(Nd nd, String targetNdCode, String returnNdCode, String resultNdCode){
        return new FilterDefBuilder(nd,targetNdCode,returnNdCode,resultNdCode);
    }

    private FilterDefBuilder(Nd nd, String targetNdCode, String returnNdCode, String resultNdCode){
        this.nd = nd;
        this.filterParamDef.setTargetNdCode(targetNdCode);
        this.filterParamDef.setResultNdCode(resultNdCode);
        this.filterParamDef.setReturnNdCode(returnNdCode);
    }


public void addFilterFd(String ndName, String fdName, String fdAlias, String logicalOperator, Object value){
    FilterFd filterFd = new FilterFd(ndName,fdName,fdAlias,logicalOperator,value);
    if(fdName.equals(ConstDef.FD_NAME_ID)){
        filterFd.setDataType(ConstDef.DATA_TYPE_LONG);
    }
    else if (fdName.equals(ConstDef.FD_NAME_PARENT_ID)){
        filterFd.setDataType(ConstDef.DATA_TYPE_LONG);
    }
    else if (fdName.equals(ConstDef.FD_NAME_META_ND_CODE)){
        filterFd.setDataType(ConstDef.DATA_TYPE_STRING);
    }
    else {
        Nd currentNd = this.nd.findNdByNdName(ndName);
        Fd fd = currentNd.getFdByName(fdName);
        filterFd.setNdName(currentNd.getNdName());
        filterFd.setDataType(fd.getDataType());
    }
    filterParamDef.addFilterFd(filterFd);
}

public void addResultFd( String ndName, String fdName,String fdAlias){
    if (fdName.equals(ConstDef.FD_NAME_ID)){
        ResultFd resultFd = new ResultFd(ConstDef.FD_NAME_ID,null,ndName);
        resultFd.setDataType(ConstDef.DATA_TYPE_LONG);
        filterParamDef.addResultFd(resultFd);
    }
    else if (fdName.equals(ConstDef.FD_NAME_PARENT_ID)){
        ResultFd resultFd = new ResultFd(ConstDef.FD_NAME_PARENT_ID,null,ndName);
        resultFd.setDataType(ConstDef.DATA_TYPE_LONG);
        filterParamDef.addResultFd(resultFd);
    }
    else if (fdName.equals(ConstDef.FD_NAME_META_ND_CODE)){
        ResultFd resultFd = new ResultFd(ConstDef.FD_NAME_META_ND_CODE,null,ndName);
        resultFd.setDataType(ConstDef.DATA_TYPE_STRING);
        filterParamDef.addResultFd(resultFd);
    }
    else {
        ResultFd resultFd = new ResultFd(fdName, fdAlias, ndName);
        Nd currentNd = this.nd.findNdByNdName(ndName);
        Fd fd = currentNd.getFdByName(fdName);
        resultFd.setNdName(currentNd.getNdName());
        resultFd.setDataType(fd.getDataType());
        filterParamDef.addResultFd(resultFd);
    }
}

    public void addResultExpression(String ndName, String expression,String fdAlias, String dataType){
        ResultFd resultFd = ResultFd.buildExpressResultFd(expression,dataType,fdAlias,ndName);
        filterParamDef.addResultFd(resultFd);
    }

    public void addAllFds(){
        Nd returnNd = nd.getDescendant(this.filterParamDef.getReturnNdCode());
        for( Fd fd : returnNd.getFds()) {
            ResultFd resultFd = new ResultFd( fd.getFdName(), null,returnNd.getNdName());
            resultFd.setNdName(returnNd.getNdName());
            resultFd.setDataType(fd.getDataType());
            this.filterParamDef.addResultFd(resultFd);
        }
        List<String> resultFdNames = filterParamDef.getResultNames(returnNd.getNdName());
        if (!resultFdNames.contains(ConstDef.FD_NAME_ID)){
            ResultFd resultFd = new ResultFd(ConstDef.FD_NAME_ID,null,returnNd.getNdName());
            resultFd.setDataType(ConstDef.DATA_TYPE_LONG);
            filterParamDef.getResultFds().add(resultFd);
        }
        if (!resultFdNames.contains(ConstDef.FD_NAME_PARENT_ID)){
            ResultFd resultFd = new ResultFd(ConstDef.FD_NAME_PARENT_ID,null,returnNd.getNdName());
            resultFd.setDataType(ConstDef.DATA_TYPE_LONG);
            filterParamDef.getResultFds().add(resultFd);
        }
        if (!resultFdNames.contains(ConstDef.FD_NAME_META_ND_CODE)){
            ResultFd resultFd = new ResultFd(ConstDef.FD_NAME_META_ND_CODE,null,returnNd.getNdName());
            resultFd.setDataType(ConstDef.DATA_TYPE_STRING);
            filterParamDef.getResultFds().add(resultFd);
        }
    }



    public FilterParamDef getFilterParamDef(){
        return this.filterParamDef;
    }


}
